from django.utils.timezone import now
from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework.serializers import ModelSerializer

from goods.models import SKU
from orders.models import OrderInfo, OrderGoods


class CartSKUSerializer2(serializers.ModelSerializer):
    """
    购物车商品数据序列化器
    """
    count = serializers.IntegerField(label='数量')

    class Meta:
        model = SKU
        fields = ('id', 'name', 'default_image_url', 'price', 'count')


class SaveOrderSerializer(ModelSerializer):
    """保存订单序列化器"""

    class Meta:
        model = OrderInfo
        fields = ('order_id', 'address', 'pay_method')
        read_only_fields = ('order_id',)  # 默认为可写
        extra_kwargs = {
            'address': {
                'write_only': True,
                'required': True,
            },
            'pay_method': {
                'write_only': True,
                'required': True
            }
        }

    def create(self, validated_data):
        """保存一个订单"""
        # 获取下单用户及请求参数: 地址，支付方式

        # 生成订单编号 20180704174607000000001

        # 订单信息表: 保存订单基本信息（新增一条订单数据）

        # 从Redis中查询购物车商品
        # cart_1 = {1: 2, 2: 2, 3: 1}
        # cart_selected_1 = {1, 2}

        # 过滤出勾选的商品id和数量，得到字典：{1: 2, 2: 2}

        # 遍历勾选的商品id
        # 查询sku对象

        # 判断库存

        # 修改sku表： 减少库存，增加销量

        # 修改spu表： 修改SPU销量 sales

        # 订单商品表: 保存订单商品信息（新增多条数据）

        # 累加订单商品总数量和总金额

        # 修改订单总数量和总金额

        # 清除购物车中已结算的商品

        # 返回新创建的订单对象 order

        # 获取下单用户及请求参数
        user = self.context['request'].user
        address = validated_data.get('address')
        pay_method = validated_data.get('pay_method')

        # 生成订单编号 20180704174607000000001
        order_id = now().strftime('%Y%m%d%H%M%S') + ('%09d' % user.id)

        # 订单信息表: 保存订单基本信息
        order = OrderInfo.objects.create(
            order_id=order_id,
            user=user,
            address=address,
            pay_method=pay_method,
            total_count=0,
            total_amount=0,
            freight=10,
            # 三元表达式
            status=OrderInfo.ORDER_STATUS_ENUM['UNPAID']  # 未支付: 待付款
            if pay_method == OrderInfo.PAY_METHODS_ENUM['ALIPAY']
            else OrderInfo.ORDER_STATUS_ENUM['UNSEND']  # 货到付款：待发货
        )

        # 从Redis中查询购物车商品
        # cart_1 = {1: 2, 2: 2}
        # cart_selected_1 = {1, 2}
        redis_conn = get_redis_connection('cart')
        redis_cart = redis_conn.hgetall('cart_%s' % user.id)  # {1: 2, 2: 2}
        selected_sku_ids = redis_conn.smembers('cart_selected_%s' % user.id)  # [1, 3]

        # 过滤出勾选的购物车商品id和数量
        carts = {}  # {1: 2, 2: 2}
        for sku_id in selected_sku_ids:
            carts[int(sku_id)] = int(redis_cart[sku_id])

        # 遍历勾选的商品
        sku_ids = carts.keys()
        for sku_id in sku_ids:
            # 查询sku对象
            sku = SKU.objects.get(id=sku_id)

            # 判断库存
            sku_count = carts[sku.id]  # 购买数量
            if sku_count > sku.stock:
                raise serializers.ValidationError('库存不足')

            # 减少库存，增加销量
            sku.stock -= sku_count
            sku.sales += sku_count
            sku.save()

            # 修改SPU销量
            sku.goods.sales += sku_count
            sku.goods.save()

            # 订单商品表: 保存订单商品信息
            OrderGoods.objects.create(
                order=order,
                sku=sku,
                count=sku_count,
                price=sku.price
            )

            # 累加订单商品总数量和总金额
            order.total_count += sku_count
            order.total_amount += (sku_count * sku.price)

        # 修改订单总数量和总金额
        order.total_amount += order.freight  # 加入运费
        order.save()

        # 清除购物车中已结算的商品
        pl = redis_conn.pipeline()
        pl.hdel('cart_%s' % user.id, *selected_sku_ids)
        pl.srem('cart_selected_%s' % user.id, *selected_sku_ids)
        pl.execute()

        # 返回新创建的订单对象
        return order

